use core::{Package, SourceId, PackageId, EitherManifest};
use util::{self, Config};
-use util::errors::{CargoResult, CargoResultExt};
+use util::errors::{CargoResult, CargoResultExt, CargoError};
use util::important_paths::find_project_manifest_exact;
use util::toml::read_manifest;
-> CargoResult<Vec<Package>> {
let mut all_packages = HashMap::new();
let mut visited = HashSet::<PathBuf>::new();
+ let mut errors = Vec::<CargoError>::new();
trace!("looking for root package: {}, source_id={}", path.display(), source_id);
if has_manifest(dir) {
read_nested_packages(dir, &mut all_packages, source_id, config,
- &mut visited)?;
+ &mut visited, &mut errors)?;
}
Ok(true)
})?;
if all_packages.is_empty() {
- Err(format!("Could not find Cargo.toml in `{}`", path.display()).into())
+ if errors.is_empty() {
+ Err(format!("Could not find Cargo.toml in `{}`", path.display()).into())
+ } else {
+ Err(errors.pop().unwrap())
+ }
} else {
Ok(all_packages.into_iter().map(|(_, v)| v).collect())
}
all_packages: &mut HashMap<PackageId, Package>,
source_id: &SourceId,
config: &Config,
- visited: &mut HashSet<PathBuf>) -> CargoResult<()> {
+ visited: &mut HashSet<PathBuf>,
+ errors: &mut Vec<CargoError>) -> CargoResult<()> {
if !visited.insert(path.to_path_buf()) { return Ok(()) }
let manifest_path = find_project_manifest_exact(path, "Cargo.toml")?;
let (manifest, nested) = match read_manifest(&manifest_path, source_id, config) {
- Err(_) => {
+ Err(err) => {
// Ignore malformed manifests found on git repositories
//
// git source try to find and read all manifests from the repository
// TODO: Add a way to exclude folders?
info!("skipping malformed package found at `{}`",
path.to_string_lossy());
+ errors.push(err);
return Ok(());
}
Ok(tuple) => tuple
for p in nested.iter() {
let path = util::normalize_path(&path.join(p));
read_nested_packages(&path, all_packages, source_id,
- config, visited)?;
+ config, visited, errors)?;
}
}
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
"));
}
+
+#[test]
+fn invalid_git_dependency_manifest() {
+ let project = project("foo");
+ let git_project = git::new("dep1", |project| {
+ project
+ .file("Cargo.toml", r#"
+ [project]
+
+ name = "dep1"
+ version = "0.5.0"
+ authors = ["carlhuda@example.com"]
+ categories = ["algorithms"]
+ categories = ["algorithms"]
+
+ [lib]
+
+ name = "dep1"
+ "#)
+ .file("src/dep1.rs", r#"
+ pub fn hello() -> &'static str {
+ "hello world"
+ }
+ "#)
+ }).unwrap();
+
+ let project = project
+ .file("Cargo.toml", &format!(r#"
+ [project]
+
+ name = "foo"
+ version = "0.5.0"
+ authors = ["wycats@example.com"]
+
+ [dependencies.dep1]
+
+ git = '{}'
+ "#, git_project.url()))
+ .file("src/main.rs", &main_file(r#""{}", dep1::hello()"#, &["dep1"]));
+
+ let git_root = git_project.root();
+
+ assert_that(project.cargo_process("build"),
+ execs()
+ .with_stderr(&format!("[UPDATING] git repository `{}`\n\
+ error: failed to load source for a dependency on `dep1`\n\
+ \n\
+ Caused by:\n \
+ Unable to update {}\n\
+ \n\
+ Caused by:\n \
+ failed to parse manifest at `[..]`\n\
+ \n\
+ Caused by:\n \
+ could not parse input as TOML\n\
+ \n\
+ Caused by:\n \
+ duplicate key: `categories` for key `project`",
+ path2url(git_root.clone()),
+ path2url(git_root),
+ )));
+}